﻿using System;
using System.Collections.Generic;
using NUnit.Framework;
using starLiGHT.Collections;
using Microsoft.Xna.Framework;

namespace starLiGHT.Engine.Tests
{
    [TestFixture]
    public class Vector2Extensions
    {
        [Test]
        public void IsValid01()
        {
            Vector2 t = new Vector2();
            Assert.IsTrue(t.IsValid());

            t.X = float.PositiveInfinity;
            Assert.IsFalse(t.IsValid());

            t.X = 0.0f;
            t.Y = float.PositiveInfinity;
            Assert.IsFalse(t.IsValid());

            t.X = float.NaN;
            t.Y = 0.0f;
            Assert.IsFalse(t.IsValid());

            t.X = 0.0f;
            t.Y = float.NaN;
            Assert.IsFalse(t.IsValid());

            t.X = float.NaN;
            Assert.IsFalse(t.IsValid());
        }

        [Test]
        public void FromString01()
        {
            Vector2 t = Vector2.Zero;
            t = t.FromString("{X=1.0f Y=2.0f}");
            Assert.AreEqual(new Vector2(1.0f, 2.0f), t);
        }

        [Test]
        public void Abs()
        {
            Vector2 t = new Vector2(-2, -3);
            t = t.Abs();

            Assert.AreEqual(2, t.X);
            Assert.AreEqual(3, t.Y);
        }

        [Test]
        public void Item01()
        {
            Vector2 t = new Vector2(1, 2);
            Assert.AreEqual(1, t.Item(0));
            Assert.AreEqual(2, t.Item(1));
        }

        [Test]
        [ExpectedException("System.ArgumentException")]
        public void Item02()
        {
            Vector2 t = Vector2.Zero;
            t.Item(2);
        }

        [Test]
        public void Item03()
        {
            Vector2 t = new Vector2(1, 2);
            t.Item(0, 3);
            t.Item(1, 4);
            //TODO: Assert.AreEqual(3, t.X);
            //TODO: Assert.AreEqual(4, t.Y);
        }

        [Test]
        [ExpectedException("System.ArgumentException")]
        public void Item04()
        {
            Vector2 t = Vector2.Zero;
            t.Item(2, 1.0f);
        }

        [Test]
        public void Cross01()
        {
            Vector2 a = new Vector2(2, 1);
            Vector2 b = new Vector2(2, 3);

            Assert.AreEqual(4, a.Cross(b));
        }

        [Test]
        public void Cross02()
        {
            Vector2 a = new Vector2(2, 1);
            float b = 3;

            Assert.AreEqual(new Vector2(3, -6), a.Cross(b));
        }

        [Test]
        public void Cross03()
        {
            Vector2 a = new Vector2(2, 1);
            float b = 3;

            Assert.AreEqual(new Vector2(-3, 6), b.Cross(a));
        }

        [Test]
        public void Perpendicular01()
        {
            Vector2 a = new Vector2(1, 2);
            a = a.Perpendicular();

            Assert.AreEqual(new Vector2(-2, 1), a);
        }

        [Test]
        public void Perpendicular02()
        {
            Vector2 a = new Vector2(1, 2);
            a = a.PerpendicularLeft();

            Assert.AreEqual(new Vector2(2, -1), a);
        }

        [Test]
        public void Round01()
        {
            Vector2 a = new Vector2(1.3f, 1.4f);
            a = a.Round();

            Assert.AreEqual(new Vector2(1, 1), a);

            a = new Vector2(1.4f, 1.5f);
            a = a.Round();

            Assert.AreEqual(new Vector2(1, 2), a);
        }

        [Test]
        public void Round02()
        {
            Vector2 a = new Vector2(1.33f, 1.44f);
            a = a.Round(1);

            Assert.AreEqual(new Vector2(1.30f, 1.40f), a);

            a = new Vector2(1.44f, 1.45f);
            a = a.Round(1);

            Assert.AreEqual(new Vector2(1.40f, 1.50f), a);
        }

        [Test]
        public void Rotate01()
        {
            Vector2 t = Vector2.UnitX;
            Vector2 a = t.Rotate(MathHelper.ToRadians(90.0f));
            a = a.Round();

            Assert.AreEqual(Vector2.UnitY, a);

            a = a.Rotate(MathHelper.ToRadians(270.0f));
            a = a.Round();
            Assert.AreEqual(Vector2.UnitX, a);

            t.Rotate(MathHelper.ToRadians(90.0f), out a);
            a = a.Round();
            Assert.AreEqual(Vector2.UnitY, a);
        }
    }
}